// electron/repository/BaseRepository.ts
import Database from 'better-sqlite3';
import path from 'path';
import PathUtils from '../utils/PathUtils';
import IdUtils from '../utils/IdUtils';

interface BaseEntity {
  _id?: string;
}

class BaseRepository<T extends BaseEntity> {
  protected readonly db: Database;
  protected readonly tableName: string;

  constructor(tableName: string) {
    this.tableName = tableName;
    const dbPath = path.join(PathUtils.getDataBaseStoragePath(), 'app.sqlite');
    this.db = new Database(dbPath);

    // 自动建表（默认字段：_id TEXT PRIMARY KEY, data TEXT）
    this.db
      .prepare(
        `CREATE TABLE IF NOT EXISTS ${this.tableName} (_id TEXT PRIMARY KEY, data TEXT)`,
      )
      .run();
  }

  protected genId(): string {
    return IdUtils.genUUID();
  }

  async insert(t: T): Promise<T> {
    const id = this.genId();
    t._id = id;
    const stmt = this.db.prepare(
      `INSERT INTO ${this.tableName} (_id, data) VALUES (?, ?)`,
    );
    stmt.run(id, JSON.stringify(t));
    return t;
  }

  async updateById(id: string, t: T): Promise<T> {
    t._id = id;
    const stmt = this.db.prepare(
      `REPLACE INTO ${this.tableName} (_id, data) VALUES (?, ?)`,
    );
    stmt.run(id, JSON.stringify(t));
    return t;
  }

  async deleteById(id: string): Promise<void> {
    const stmt = this.db.prepare(`DELETE FROM ${this.tableName} WHERE _id = ?`);
    stmt.run(id);
  }

  async findById(id: string): Promise<T | null> {
    const stmt = this.db.prepare(
      `SELECT data FROM ${this.tableName} WHERE _id = ?`,
    );
    const row = stmt.get(id);
    return row ? (JSON.parse(row.data) as T) : null;
  }

  async findAll(): Promise<T[]> {
    const stmt = this.db.prepare(`SELECT data FROM ${this.tableName}`);
    const rows: { data: string }[] = stmt.all();
    return rows.map((row) => JSON.parse(row.data) as T);
  }

  async truncate(): Promise<void> {
    const stmt = this.db.prepare(`DELETE FROM ${this.tableName}`);
    stmt.run();
  }
}

export default BaseRepository;
